home *** CD-ROM | disk | FTP | other *** search
- /*
- * Spawn a shell with the stdin and stdout swapped with the remote
- * system, ie:
- * +----------+
- * TTYin ------------> stdin | |
- * | shell |
- * TTYout <---------- stdout | |
- * +----------+
- *
- * An undocumented feature: The external protocol gateway
- * can be used to pipe the output of a normal Unix command to the
- * remote system.
- */
-
- #include <stdio.h>
- #include <signal.h>
- #include <curses.h>
- #include <errno.h>
- #include "config.h"
-
- #ifdef BSD
- #ifndef SIGCLD
- #define SIGCLD SIGCHLD
- #endif /* SIGCLD */
- #include <sys/file.h>
- #else /* BSD */
- #include <fcntl.h>
- #endif /* BSD */
-
- void
- do_extrnl(cmd)
- char *cmd;
- {
- extern int fd, errno;
- WINDOW *xt_win, *newwin();
- SIG_TYPE (*istat)(), (*qstat)(), (*cstat)();
- int epid, want_out;
- unsigned int sleep();
- void _exit(), input_off();
-
- input_off();
- /* a full window */
- xt_win = newwin(LINES, COLS, 0, 0);
- nl();
- touchwin(xt_win);
- wrefresh(xt_win);
-
- if (!(epid = fork())) {
- /* create a new process group ID */
- #ifdef BSD
- setpgrp(0, getpid());
- #else /* BSD */
- setpgrp();
- #endif /* BSD */
- /* swap the stdin */
- close(0);
- dup(fd);
- /* swap the stdout */
- close(1);
- dup(fd);
- #ifdef SETUGID
- setgid(getgid());
- setuid(getuid());
- #endif /* SETUGID */
- execl("/bin/sh", "sh", "-c", cmd, (char *) 0);
- _exit(1);
- }
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
- cstat = signal(SIGCLD, SIG_IGN);
-
- /*
- * Check the keyboard while the external program is running. If
- * the user hits the <ESC> key, then kill the entire process
- * group associated with the new shell.
- */
- want_out = 0;
- while(1) {
- switch(wait_key(stdscr, 1)) {
- case -1: /* timed out */
- break;
- case 27: /* a user abort */
- #ifdef BSD
- killpg(epid, SIGKILL);
- #else /* BSD */
- kill(-epid, SIGKILL);
- #endif /* BSD */
- want_out++;
- break;
- default:
- beep();
- break;
- }
- if (want_out)
- break;
- /* see if the process it still active */
- if ((kill(epid, 0) == -1) && errno == ESRCH)
- break;
- }
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
- signal(SIGCLD, cstat);
- /* the tty may have been clobbered */
- sleep(1);
- fixterm();
- nonl();
-
- clearok(curscr, TRUE);
- werase(xt_win);
- wrefresh(xt_win);
- delwin(xt_win);
- return;
- }
-